feat: add Resource collection for programmatic content#94
Open
riboflavin wants to merge 3 commits into
Open
Conversation
Introduce a dedicated Strapi collection for programmatic content with campaign grouping, separate from editorial Articles.
Add per-endpoint OpenAPI docs for the /resources REST API.
Refresh OpenAPI-derived client types and Strapi content type definitions.
There was a problem hiding this comment.
⚠️ AI Review (Codex GPT-5, worked 12m): Resource contracts do not yet match the schema and cow.fi consumer
Finding: [BLOCKING] Fix ResourceRequest before publishing the client types
- Location:
src/extensions/documentation/documentation/1.0.0/full_documentation.json:29477, propagated tosrc/gen/types.ts:11369. - The runtime Resource schema requires
title,description,slug,campaign, andpublishDateVisible. ResourceRequestinstead resemblesArticleRequest: it requiresfeatured, includescategories,authorsBio, andtags, omitscampaign, and markstitleandslugoptional.- Both
POST /resourcesandPUT /resources/{id}reference this request schema. Consumers therefore cannot express a valid typed Resource mutation without casts and are guided toward fields the runtime model does not accept. - The response schema also marks required
titleandslugas optional.
Suggested fix
- Correct the OpenAPI generation/source so Resource request and response schemas match the committed content type. If updates are partial, consider separate create and update request schemas.
- Regenerate
src/gen/types.tsand add a contract check coveringcampaign, required fields, and the absence of Article-only fields.
Finding: [BLOCKING] Align the fields query type with the cow.fi consumer
- Location:
src/api/resource/documentation/1.0.0/resource.json:131, propagated tosrc/gen/types.ts:17775. - The new
GET /resourcesoperation declaresfields?: string, while the companion cow.fi implementation passesfields: ['slug', 'campaign']. - That PR explicitly waits for this package's typed
/resourcesendpoints. With the contract currently generated here, the two PRs still will not typecheck together after the package bump.
Suggested fix
- If the intended wire shape is the array used by the query serializer, define
fieldsas an array of strings in the Resource OpenAPI parameter and regenerate the full documentation and client types. - Otherwise, update cow.fi to use a documented, runtime-verified string encoding. In either case, add a small compile-time/integration check for the exact
getAllResourceSlugsquery.
Finding: [QUESTION] Align the Resource block choices with what cow.fi can render
- Location:
src/api/resource/content-types/resource/schema.json:40. - CMS authors can select
shared.media,shared.quote,shared.rich-text,shared.slider, andshared.video-embed. - The companion renderer only renders blocks containing a string
body. Media, slider, and video blocks disappear; quotes are rendered as plain rich text, dropping their title/author semantics. - Is v1 intentionally rich-text-only, or should cow.fi support every block exposed to Resource authors?
Suggested fix
- For a rich-text-only v1, restrict the Resource dynamic zone accordingly. Otherwise, add matching cow.fi renderers before exposing the other block choices, plus one fixture/test per supported block type.
Review scope and related context
- Cross-checked CMS PR head
0849e22against companion cow.fi PR head4f15eb3, including the Resource schema, OpenAPI operations, generated TypeScript, query construction, and page renderer. - Apart from the findings above, the collection and public read shape align with the planned
/resources,/resources/[campaign], and/resources/[campaign]/[slug]pages. - The CMS build, OpenAPI generation, and TypeScript compilation pass. The current Docker check is red only because the GitHub App cannot write the organization package to GHCR, not because of this code.
- No other CMS review thread covers these findings.
🤖 Prompt for AI agents
Verify these findings against the current heads of cowprotocol/cms#94 and
cowprotocol/cowswap#7846, and fix only those still valid.
1. Make ResourceRequest and Resource response requiredness match the Resource
content type, including campaign and excluding Article-only fields.
2. Make the GET /resources fields parameter and cow.fi's
fields: ['slug', 'campaign'] query agree without casts, using a wire format
verified against Strapi and the configured query serializer.
3. Decide whether Resource v1 is rich-text-only. Either restrict the CMS block
choices or render every allowed block faithfully in cow.fi.
Regenerate the full OpenAPI document and src/gen/types.ts, then add focused
contract/type checks for the mutation schema, slug query, and supported blocks.
Generated using the pr-review skill from the CoW Protocol skills repo.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resourcecollection for programmatic/batch content, separate from editorialArticle/ Learn content.campaignfield (kebab-case slug) for URL grouping; no categories, tags, authors, or featured for v1.@cowprotocol/cmsclient / Strapi types.Proposed site URL model (frontend follow-up)
/resources— list campaigns/resources/[campaign]— list resources in a campaign/resources/[campaign]/[slug]— resource detail (global slug uniqueness)Discoverability: footer link only (no main nav) in the companion cow-fi PR.
Post-merge ops
Please enable in staging/prod after deploy:
resource.find,resource.findOneThen publish a new
@cowprotocol/cmsversion so the cow-fi PR can depend on typed/resourcesendpoints.